﻿using FirstFloor.ModernUI.Windows.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TanmiaGrp.GeneralLedger.Core;
using TanmiaGrp.Basis;

namespace TanmiaGrp.GeneralLedger.WinApp.Scenarios
{
    /// <summary>
    /// Interaction logic for AccountBrowserView.xaml
    /// </summary>
    public partial class AccountBrowserView : UserControl
    {
        private AccountBrowserViewModel viewModel;

        public AccountBrowserView()
        {
            InitializeComponent();
            DataContext = viewModel = new AccountBrowserViewModel { Close = CloseView };
        }

        /// <summary>
        /// Called when Pop-out button is pressed, to popup the window from the docked workspace.
        /// </summary>
        private void OnPopout(object sender, RoutedEventArgs e)
        {
            // Create new (Editor | Browser)View and assign the same (Editor | Browser)ViewModel object to it.
            // Hide the popout button because no need to popout an already popout-ed (Editor | Browser)View.
            AccountBrowserView popoutBrowserView = new AccountBrowserView();
            popoutBrowserView.DataContext = this.DataContext;
            popoutBrowserView.windowBar.PopoutVisibility = System.Windows.Visibility.Collapsed;

            // Create and show the popuped window.
            FloatWindow popoutWindow = new FloatWindow()
            {
                Content = popoutBrowserView,
                ShowActivated = true,
                Owner = Application.Current.MainWindow
            };

            popoutWindow.Show();

            // Notify MainWindowViewModel to keep track for new popoutWindow.
            Events.FloatWindowShown.Fire(popoutWindow);
        }

        /// <summary>
        /// Close the View that contains current (Editor | Browser)View.
        /// Because one ViewModel object may control many (Editor | Browser)ViewModel objects, we have to determine where 
        /// currrent (Editor | Browser)View is contained to close it accordingly.
        /// </summary>
        /// <param name="sender">Represetnt the button that send Close view.</param>
        public void CloseView(object sender)
        {
            FrameworkElement senderElm = sender as FrameworkElement;

            // check if GroupEditorView is contained within FloatWindow
            FloatWindow floatWindow = senderElm.TryGetParent<FloatWindow>();
            if (floatWindow != null)
                floatWindow.Close();

            // otherwise if GroupEditorView is contained within ModernFrame that mean it is docked.
            ModernFrame modernFrame = senderElm.TryGetParent<ModernFrame>();
            if (modernFrame != null)
                modernFrame.Source = null;
        }

        private void OnAccountDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListViewItem lvItem = sender as ListViewItem;
            Account obj = lvItem.DataContext as Account;
            if (obj.AccountChildren.Count > 0)
            {
                obj.IsSelected = true;
                if (obj.Parent != null)
                    obj.Parent.IsExpanded = true;
                obj.IsExpanded = true;
            }
        }

        private void OnAccountContextMenuClicked(object sender, RoutedEventArgs e)
        {
            MenuItem item = sender as MenuItem;
            Account selectedAccount = GetSelectedAccount(item);

            if (item.Name == "miEdit")
                viewModel.EditCommand.Execute(selectedAccount);
            else if (item.Name == "miAdd")
                viewModel.AddCommand.Execute(selectedAccount);
        }

        private Account GetSelectedAccount(MenuItem item)
        {
            ListViewItem listItem = item.CommandParameter as ListViewItem;
            if (listItem != null)
                return listItem.Content as Account;

            TreeViewItem treeItem = item.CommandParameter as TreeViewItem;
            if (treeItem != null)
                return treeItem.Header as Account;

            return null;
        }

        private T ExtractItem<T>(FrameworkElement fe, UIElement parent)
            where T : class
        {
            Point p = fe.TranslatePoint(new Point(0, 0), parent);
            DependencyObject obj = parent.InputHitTest(p) as DependencyObject;
            while (obj != null && !(obj is T))
                obj = VisualTreeHelper.GetParent(obj);

            return obj as T;
        }

        private void OnAccountLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement original = e.OriginalSource as FrameworkElement;
            UIElement parent = sender as UIElement;

            TreeViewItem tvItem = ExtractItem<TreeViewItem>(original, parent);
            if (tvItem != null)
                viewModel.SelectedAccount = tvItem.DataContext as Account;

            ListViewItem lvItem = ExtractItem<ListViewItem>(original, parent);
            if (lvItem != null)
                viewModel.SelectedAccount = lvItem.DataContext as Account;
        }
    }
}